package com.papers.juan.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.papers.common.core.controller.BaseController;
import com.papers.common.core.domain.PageQuery;
import com.papers.common.core.domain.R;
import com.papers.common.core.page.TableDataInfo;
import com.papers.common.enums.YesOrNo;
import com.papers.common.exception.ServiceException;
import com.papers.common.utils.BeanCopyUtils;
import com.papers.common.utils.poi.ExcelUtil;
import com.papers.juan.domain.TJuanPaperBakeup;
import com.papers.juan.domain.TJuanQuestion;
import com.papers.juan.domain.bean.PaperDetailBean;
import com.papers.juan.domain.bean.PaperExportBean;
import com.papers.juan.domain.bean.PaperStatisticsBean;
import com.papers.juan.domain.bean.QuestionInfoBean;
import com.papers.juan.domain.bean.QuestionPropertyImportBean;
import com.papers.juan.domain.bean.RandomTakeOutPaperBean;
import com.papers.juan.domain.dto.PaperBakeupDto;
import com.papers.juan.service.ITJuanPaperBakeupService;
import com.papers.juan.service.PaperExportService;
import com.papers.juan.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.http.MediaType;
import org.springframework.util.ResourceUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * 试卷备份控制器
 *
 * @author libo
 * @date 2022/12/2 11:30
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/juan/juanPaperBakeup")
public class TJuanPaperBakeupController extends BaseController {

    private final ITJuanPaperBakeupService juanPaperBakeupService;


    private final PaperExportService paperExportService;

    /**
     * 导出试卷word
     *
     * @param id       试卷备份id
     * @param response response响应
     */
    @PostMapping("/exportPaper/{id}")
    public void exportPaper(HttpServletResponse response, @NotEmpty(message = "id不能为空") @PathVariable String id) {
        paperExportService.exportPaper(response, id);
    }

    /**
     * 导出试卷答案word
     *
     * @param id       试卷备份id
     * @param response response响应
     */
    @PostMapping("/exportPaperAnswer/{id}")
    public void exportPaperAnswer(HttpServletResponse response, @NotEmpty(message = "id不能为空") @PathVariable String id) {
        paperExportService.exportPaperAnswer(response, id);
    }

    /**
     * 根据id获取备份信息
     *
     * @param id id
     */
    @GetMapping("/queryBakeupById/{id}")
    public R<TJuanPaperBakeup> queryBakeupById(@PathVariable("id") String id) {
        return R.ok(juanPaperBakeupService.queryBakeupById(id));
    }

    /**
     * 根据试卷id新增备份信息
     *
     * @param paperId 试卷id
     */
    @GetMapping("/insertByPaperId/{paperId}")
    public R<Void> insertByPaperId(@PathVariable("paperId") String paperId) {
        juanPaperBakeupService.insertByPaperId(paperId);
        return R.ok();
    }

    /**
     * 修改试卷备份信息
     *
     * @param bakeup 试卷备份信息
     */
    @PostMapping("/updateBakeup")
    public R<Void> updateBakeup(@RequestBody TJuanPaperBakeup bakeup) {
        return toAjax(juanPaperBakeupService.updateBakeup(bakeup));
    }

    /**
     * 删除试卷备份信息
     *
     * @param id 试卷备份id
     */
    @DeleteMapping("/deleteById/{id}")
    public R<Void> deleteById(@PathVariable String id) throws FileNotFoundException {
        juanPaperBakeupService.deleteById(id);
        return R.ok();
    }

    /**
     * 获取试卷备份列表
     *
     * @param dto       试卷备份bto
     * @param pageQuery 分页条件
     * @return 试卷备份列表
     */
    @GetMapping("/queryBakeupList")
    public TableDataInfo<TJuanPaperBakeup> queryBakeupList(PaperBakeupDto dto, PageQuery pageQuery) {
        return juanPaperBakeupService.queryBakeupList(dto, pageQuery);
    }

    /**
     * 获取已被抽取的试卷备份列表
     *
     * @param dto       试卷备份bto
     * @param pageQuery 分页条件
     * @return 试卷备份列表
     */
    @GetMapping("/queryBeenTakenOutBakeupList")
    public TableDataInfo<TJuanPaperBakeup> queryBeenTakenOutBakeupList(PaperBakeupDto dto, PageQuery pageQuery) {
        dto.setIsTakenOut(YesOrNo.YES.getKey());
        return juanPaperBakeupService.queryBakeupList(dto, pageQuery);
    }

    /**
     * 导出抽卷历史记录列表（抽卷报表）
     */
    @PostMapping("/exportTakeOutPaperRecords")
    public void exportTakeOutPaperRecords(PaperBakeupDto dto, HttpServletResponse response) {
        dto.setIsTakenOut(YesOrNo.YES.getKey());
        List<TJuanPaperBakeup> list = juanPaperBakeupService.queryBakeupList(dto, new PageQuery()).getRows();
        if (CollectionUtils.isEmpty(list)) {
            throw new ServiceException("抽卷历史记录列表不能为空！");
        }
        ExcelUtil.exportExcel(list, "抽卷历史记录", TJuanPaperBakeup.class, response);
    }

    /**
     * 获取未被抽取的试卷备份列表
     *
     * @param dto       试卷备份bto
     * @param pageQuery 分页条件
     * @return 试卷备份列表
     */
    @GetMapping("/queryUnBeenTakenOutBakeupList")
    public TableDataInfo<TJuanPaperBakeup> queryUnBeenTakenOutBakeupList(PaperBakeupDto dto, PageQuery pageQuery) {
        dto.setIsTakenOut(YesOrNo.NO.getKey());
        return juanPaperBakeupService.queryBakeupList(dto, pageQuery);
    }

    /**
     * 随机抽卷
     *
     * @param bean 随机抽取试卷bean
     * @return 试卷列表
     */
    @PostMapping("/randomTakeOutPaper")
    public R<List<TJuanPaperBakeup>> randomTakeOutPaper(@RequestBody RandomTakeOutPaperBean bean) {
        return R.ok(juanPaperBakeupService.randomTakeOutPaper(bean));
    }

    /**
     * 根据id获取题目列表
     *
     * @param id 备份id
     */
    @GetMapping("/queryQuestionsById/{id}")
    public R<List<TJuanQuestion>> queryQuestionsById(@PathVariable("id") String id) {
        return R.ok(juanPaperBakeupService.queryQuestionsById(id));
    }

    /**
     * 根据id获取试卷备份统计数据
     *
     * @param id 备份id
     */
    @GetMapping("/queryPaperStatisticsById/{id}")
    public R<PaperStatisticsBean> queryPaperStatisticsById(@PathVariable("id") String id) {
        return R.ok(juanPaperBakeupService.queryPaperStatisticsById(id));
    }

    /**
     * 导出试卷备份json信息
     *
     * @param response 响应
     * @param id       试卷备份id
     */
    @PostMapping("/exportPaperBackupJson/{id}")
    public void exportPaperBackupJson(HttpServletResponse response, @NotEmpty(message = "id不能为空") @PathVariable String id) {
        juanPaperBakeupService.exportPaperBackupJson(id, response);
    }

    /**
     * 导入试卷备份json信息
     */
    @PostMapping("/importPaperBackupJson")
    public R<Void> importPaperBackupJson(@RequestPart("file") MultipartFile file) {
        if (null == file) {
            return R.fail("请选择一个文件");
        }
        juanPaperBakeupService.importPaperBackupJson(file);
        return R.ok();
    }

    /**
     * 导入试卷备份文件
     *
     * @param courseId  试卷备份文件
     * @param excelFile 试卷试题属性文件
     * @param wordFile  试卷word文件
     */
    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Void> importData(String courseId, @RequestPart("excelFile") MultipartFile excelFile, @RequestPart("wordFile") MultipartFile wordFile) {
        List<QuestionPropertyImportBean> list;
        try {
            list = EasyExcel.read(excelFile.getInputStream()).headRowNumber(3).head(QuestionPropertyImportBean.class)
                .sheet().doReadSync();
        } catch (Exception e) {
            log.error("读取数据失败：{}", e.getMessage());
            throw new ServiceException("读取数据失败，请正确填写数据！");
        }

        if (0 == list.size()) {
            throw new ServiceException("导入失败，没有读取到导入数据！");
        }
        juanPaperBakeupService.importData(list, courseId, wordFile);
        return R.ok();
    }

    /**
     * 下载试卷备份文件
     */
    @PostMapping(value = "/downloadPaper/{id}")
    public R<Void> downloadPaper(@PathVariable("id") String id, HttpServletResponse response) throws FileNotFoundException {
        String basePath = ResourceUtils.getURL("classpath:").getPath() + "static/papers/";
        TJuanPaperBakeup juanPaperBakeup = juanPaperBakeupService.queryBakeupById(id);
        String fileName = juanPaperBakeup.getNewPaperCode() + ".docx";
        FileUtil.download(response, basePath + fileName, fileName);
        return R.ok();
    }

    /**
     * 导出试卷
     *
     * @param response response
     * @param id       试卷备份id
     */
    @PostMapping("/exportData/{id}")
    public void exportData(HttpServletResponse response, @NotEmpty(message = "试卷备份id不能为空") @PathVariable String id)
        throws UnsupportedEncodingException {
        // 试卷详情
        PaperDetailBean paperDetail = juanPaperBakeupService.queryPaperDetailById(id);
        // 题目列表
        List<QuestionInfoBean> questionInfoList = paperDetail.getQuestionInfoList();
        // 题目数量
        int questionNum = questionInfoList.size();
        List<PaperExportBean> list = Lists.newArrayList();
        for (int i = 0; i < questionInfoList.size(); i++) {
            PaperExportBean paperExportBean = new PaperExportBean();
            BeanCopyUtils.copy(questionInfoList.get(i), paperExportBean);
            if (i == 0) {
                BeanCopyUtils.copy(paperDetail, paperExportBean);
            }
            list.add(paperExportBean);
        }

        // 设置excel表头样式
        WriteSheet sheet = EasyExcel.writerSheet("试卷信息").head(PaperExportBean.class).sheetNo(1).build();
        // 设置excel表格样式
        ExcelWriter writer = null;
        try {
            if (1 == questionNum) {
                writer = EasyExcel.write(response.getOutputStream())
                    // 设置表头从第2行开始
//                    .useDefaultStyle(true).relativeHeadRowIndex(1)
                    // 设置下拉框
//                    .registerWriteHandler(new ExportPaperSelectSheetWriteHandler(getDropDownMap()))
                    .needHead(true).excelType(ExcelTypeEnum.XLSX).build();
            } else if (1 < questionNum) {
                writer = EasyExcel.write(response.getOutputStream())
                    // 设置表头从第2行开始
//                    .useDefaultStyle(true).relativeHeadRowIndex(1)
                    // 设置下拉框
//                    .registerWriteHandler(new ExportPaperSelectSheetWriteHandler(getDropDownMap()))
                    .needHead(true).excelType(ExcelTypeEnum.XLSX)
                    // 前12列的questionNum的行数进行合并
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 0))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 1))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 2))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 3))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 4))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 5))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 6))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 7))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 8))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 9))
                    .registerWriteHandler(new LoopMergeStrategy(questionNum, 10))
                    .build();
            }
        } catch (IOException e) {
            log.error("导出数据失败：{}", e.getMessage());
            throw new ServiceException("导出数据失败！");
        }
        // 写入excel数据
        writer.write(list, sheet);
        // 通知浏览器以附件的形式下载处理，设置返回头要注意文件名有中文
        response.setHeader("Content-disposition", "attachment;filename=" + new String("试卷信息".getBytes("gb2312"),
            "ISO8859-1") + ".xlsx");
        response.setContentType("multipart/form-data");
        response.setCharacterEncoding("utf-8");
        writer.finish();
    }

}
